package com.fyakm.javaprojectanalysis.common.util;

import java.io.*;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/***
 * Zip文件处理工具类
 */
public class ZipUtil {


    /**
     * 解压zip文件到目录
     * @param zipFilePath   zip文件路径
     * @param destDirectory 解压到那个目录下
     * @throws IOException
     */
    public static void unzip(String zipFilePath, String destDirectory) throws IOException {
        File destDir = new File(destDirectory);
        if (!destDir.exists()) {
            destDir.mkdir();
        }

        try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath))) {
            ZipEntry entry;

            // 遍历ZIP文件中的每一个条目
            while ((entry = zipInputStream.getNextEntry()) != null) {
                String entryName = entry.getName();
                String filePath = destDirectory + File.separator + entryName;

                // 如果条目是目录，则创建目录
                if (entry.isDirectory()) {
                    File dir = new File(filePath);
                    dir.mkdirs();
                } else {
                    // 如果条目是文件，则写入文件内容
                    extractFile(zipInputStream, filePath);
                }

                zipInputStream.closeEntry();
            }
        }
    }


    /**
     * 解压zip文件到目录
     * @param inputStream   输入流
     * @param destDirectory 解压到那个目录下
     * @throws IOException
     */
    public static void unzip(InputStream inputStream, String destDirectory) throws IOException {
        File destDir = new File(destDirectory);
        if (!destDir.exists()) {
            destDir.mkdir();
        }
        try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
            ZipEntry entry;

            // 遍历ZIP文件中的每一个条目
            while ((entry = zipInputStream.getNextEntry()) != null) {
                String entryName = entry.getName();
                String filePath = destDirectory + File.separator + entryName;

                // 如果条目是目录，则创建目录
                if (entry.isDirectory()) {
                    File dir = new File(filePath);
                    dir.mkdirs();
                } else {
                    // 如果条目是文件，则写入文件内容
                    extractFile(zipInputStream, filePath);
                }

                zipInputStream.closeEntry();
            }
        }
    }




    /**
     * 文件拷贝
     * @param zipInputStream    zip输入流
     * @param filePath          文件路径
     * @throws IOException
     */
    private static void extractFile(ZipInputStream zipInputStream, String filePath) throws IOException {
        File file = new File(filePath);
        File parentFile = file.getParentFile();
        if(!parentFile.exists()){
            parentFile.mkdirs();
        }

        try (BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(filePath))) {
            byte[] buffer = new byte[1024];
            int bytesRead;

            while ((bytesRead = zipInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }
    }




    public static void zipDirectory(String sourceDirPath, String zipFilePath) throws IOException {
        File dir = new File(sourceDirPath);
        if (!dir.exists()) {
            throw new FileNotFoundException("Source directory not found: " + sourceDirPath);
        }

        FileOutputStream fos = new FileOutputStream(zipFilePath);
        ZipOutputStream zos = new ZipOutputStream(fos);

        File[] files = dir.listFiles();
        if (files != null && files.length > 0) {
            for (File file : files) {
                if (file.isDirectory()) {
                    zipSubDirectory(file, file.getPath().replace(sourceDirPath, ""), zos);
                } else {
                    addToZipFile(file, file.getPath().replace(sourceDirPath + File.separator, ""), zos);
                }
            }
        }

        zos.closeEntry();
        zos.close();
        fos.close();
    }

    private static void zipSubDirectory(File directory, String dirPath, ZipOutputStream zos) throws IOException {
        File[] files = directory.listFiles();
        if (files != null && files.length > 0) {
            for (File file : files) {
                String filePath = dirPath + File.separator + file.getName();
                if (file.isDirectory()) {
                    zos.putNextEntry(new ZipEntry(filePath + "/"));
                    zipSubDirectory(file, filePath, zos);
                } else {
                    addToZipFile(file, filePath, zos);
                }
            }
        }
    }

    private static void addToZipFile(File file, String filePath, ZipOutputStream zos) throws IOException {
        FileInputStream fis = new FileInputStream(file);
        ZipEntry zipEntry = new ZipEntry(filePath);
        zos.putNextEntry(zipEntry);

        byte[] bytes = new byte[1024];
        int length;
        while ((length = fis.read(bytes)) >= 0) {
            zos.write(bytes, 0, length);
        }

        zos.closeEntry();
        fis.close();
    }

    public static void main(String[] args) {
        try {
            String sourceDirPath = "C:\\Users\\fyakm\\Desktop\\temp\\S2SH-master"; // 替换为你的目录路径
            String zipFilePath = "C:\\Users\\fyakm\\Desktop\\temp\\outputZip"; // 替换为你的ZIP文件路径
            zipDirectory(sourceDirPath, zipFilePath);
            System.out.println("Zip file created successfully!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
